package com.xk._04regEx;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @description: 体验正则表达式的威力，给我们文本处理带来了哪些便利
 * @author: xu
 * @date: 2022/11/1 13:45
 */
public class RegExp_01 {
    public static void main(String[] args) {
        // 假定，编写了爬虫，从百度页面得到如下文本
        /*
        String content = "\t20世纪90年代，硬件领域出现了单片式计算机系统，这种价格低廉的系统" +
                "一出现就立即引起了自动控制领域人员的注意，因为使用它可以大幅度提升消费类电子" +
                "产品（如电视机顶盒、面包烤箱、移动电话等）的智能化程度。Sun公司为了抢占市场先机，" +
                "在1991年成立了一个称为Green的项目小组，帕特里克、詹姆斯·高斯林、麦克·舍林丹和其他" +
                "几个工程师一起组成的工作小组在加利福尼亚州门洛帕克市沙丘路的一个小工作室里面研究开发" +
                "新技术，专攻计算机在家电产品上的嵌入式应用。\n" +
                "\t由于C++所具有的优势，该项目组的研究人员首先考虑采用C++来编写程序。" +
                "但对于硬件资源极其匮乏的单片式系统来说，C++程序过于复杂和庞大。另外由于消费电子" +
                "产品所采用的嵌入式处理器芯片的种类繁杂，如何让编写的程序跨平台运行也是个难题。" +
                "为了解决困难，他们首先着眼于语言的开发，假设了一种结构简单、符合嵌入式应用需要的硬" +
                "件平台体系结构并为其制定了相应的规范，其中就定义了这种硬件平台的二进制机器码指令" +
                "系统（即后来成为“字节码”的指令系统），以待语言开发成功后，能有半导体芯片生产商开发" +
                "和生产这种硬件平台。对于新语言的设计，Sun公司研发人员并没有开发一种全新的语言，" +
                "而是根据嵌入式软件的要求，对C++进行了改造，去除了留在C++的一些不太实用及影响安全的成分，" +
                "并结合嵌入式系统的实时性要求，开发了一种称为Oak的面向对象语言。";
         */

        String content = "私有地址（Private address）属于非注册地址，专门为组织机构内部使用。\n" +
                "以下列出留用的内部私有地址\n" +
                "A类 10.0.0.0--10.255.255.255\n" +
                "B类 172.16.0.0--172.31.255.255\n" +
                "C类 192.168.0.0--192.168.255.255" +
                "A类IP地址\n" +
                "一个A类IP地址是指， 在IP地址的四段号码中，第一段号码为网络号码，剩下的三段号码为本地计算机的号码。如果用二进制表示IP地址的话，A类IP地址就由1字节的网络地址和3字节主机地址组成，网络地址的最高位必须是“0”。A类IP地址中网络的标识长度为8位，主机标识的长度为24位，A类网络地址数量较少，有126个网络，每个网络可以容纳主机数达1600多万台。\n" +
                "A类IP地址 地址范围1.0.0.1到127.255.255.254 [2]  （二进制表示为：00000001 00000000 00000000 00000001 - 01111111 11111111 11111111 11111110）。最后一个是广播地址。\n" +
                "B类IP地址\n" +
                "一个B类IP地址是指，在IP地址的四段号码中，前两段号码为网络号码。如果用二进制表示IP地址的话，B类IP地址就由2字节的网络地址和2字节主机地址组成，网络地址的最高位必须是“10”。B类IP地址中网络的标识长度为16位，主机标识的长度为16位，B类网络地址适用于中等规模的网络，有16384个网络，每个网络所能容纳的计算机数为6万多台。\n" +
                "B类IP地址地址范围128.0.0.1-191.255.255.254 [1]  （二进制表示为：10000000 00000000 00000000 00000001----10111111 11111111 11111111 11111110）。 最后一个是广播地址。\n" +
                "B类IP地址的子网掩码为255.255.0.0，每个网络支持的最大主机数为256的2次方-2=65534台。\n" +
                "C类IP地址\n" +
                "一个C类IP地址是指，在IP地址的四段号码中，前三段号码为网络号码，剩下的一段号码为本地计算机的号码。如果用二进制表示IP地址的话，C类IP地址就由3字节的网络地址和1字节主机地址组成，网络地址的最高位必须是“110”。C类IP地址中网络的标识长度为24位，主机标识的长度为8位，C类网络地址数量较多，有209万余个网络。适用于小规模的局域网络，每个网络最多只能包含254台计算机。\n" +
                "C类IP地址范围192.0.0.1-223.255.255.254 [1]  （二进制表示为: 11000000 00000000 00000000 00000001 - 11011111 11111111 11111111 11111110）。\n" +
                "C类IP地址的子网掩码为255.255.255.0，每个网络支持的最大主机数为256-2=254台\n" +
                "D类IP地址\n" +
                "D类IP地址在历史上被叫做多播地址(multicast address)，即组播地址。在以太网中，多播地址命名了一组应该在这个网络中应用接收到一个分组的站点。多播地址的最高位必须是“1110”，范围从224.0.0.0到239.255.255.255。\n" +
                "特殊的网址\n" +
                "每一个字节都为0的地址（“0.0.0.0”）对应于当前主机；\n" +
                "IP地址中的每一个字节都为1的IP地址（“255．255．255．255”）是当前子网的广播地址；\n" +
                "IP地址中凡是以“11110”开头的E类IP地址都保留用于将来和实验使用。\n" +
                "IP地址中不能以十进制“127”作为开头，该类地址中数字127．0．0．1到127．255．255．255用于回路测试，如：127.0.0.1可以代表本机IP地址，用“http://127.0.0.1”就可以测试本机中配置的Web服务器。\n" +
                "网络ID的第一个6位组也不能全置为“0”，全“0”表示本地网络。\n" +
                "子网\n" +
                "引入子网掩码(NetMask)，从逻辑上把一个大网络划分成一些小网络。子网掩码是由一系列的1和0构成，通过将其同IP地址做“与”运算来指出一个IP地址的网络号是什么。对于传统IP地址分类来说，A类地址的子网掩码是255.0.0.0；B类地址的子网掩码是255.255.0.0；C类地址的子网掩码是255.255.255.0。例如，如果要将一个B类网络166.111.0.0划分为多个C类子网来用的话，只要将其子网掩码设置为255.255.255.0即可，这样166.111.1.1和166.111.2.1就分属于不同的网络了。像这样，通过较长的子网掩码将一个网络划分为多个网络的方法就叫做划分子网(Subnetting)。 [1] \n" +
                "超网\n" +
                "超网(Supernetting)是同子网类似的概念，它通过较短的子网掩码将多个小网络合成一个大网络。例如，一个单位分到了8个C类地址：202.120.224.0 ～ 202.120.231.0，只要将其子网掩码设置为255.255.248.0，就能使这些C类网络相通。\n" +
                "无类间路由\n" +
                "无类域间路由(CIDR，Classless Inter-Domain Routing)地址根据网络拓扑来分配，可以将连续" +
                "的一组网络地址分配给一家公司，并使整组地址作为一个网络地址(比如使用超网技术)，在外部路由表上只有一个路由表项。这样既解决了地址匮乏问题，又解决了路由表膨胀的问题。另外，CIDR还将整个世界分" +
                "为四个地区，给每个地区分配了一段连续的C类地址，分别是：欧洲(194.0.0.0～195.255.255.255)、北美(198.0.0.0～199.255.255.255)、中南美(200.0.0.0～201.255.255.255)和亚太" +
                "(202.0.0.0～203.255.255.255)。这样，当一个亚太地区以外的路由器收到前8位为202或203的数据报时，它只需要将其放到通向亚太地区的路由即可，而对后24位的路由则可以在数据报到达亚太地区后再进行处理，这样就大大缓解了路由表膨胀的问题。";


        // 提取文章中所有的英文单词  "[a-zA-z]+"
        // 提取文章中所有的数字     "[0-9]+"
        // 提取文章中所有的数字和英文单词    “([0-9]+)|([a-zA-z]+)”
        // 提取百度热搜 标题    "<a target=\"_blank\" title=\"(\\S*)\""  matcher.group(1)
        // 提取IP地址       "\\d+\\.\\d+\\.\\d+\\.\\d+"
        //
        //  1.传统方法。使用遍历方式，代码量大，效率不高
        //  2.正则表达式

        // 1.先创建一个Pattern对象，即模式对象，可以理解成就是一个正则表达式对象
        //Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-z]+)");
        Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");
        // 2.创建一个匹配器对象
        // 理解：就是 matcher 匹配器按照 pattern(模式/样式)，到 content 文本中去匹配
        // 找到就返回true，否则就返回false
        Matcher matcher = pattern.matcher(content);
        // 3.可以开始循环匹配
        while (matcher.find()) {
            // 匹配内容，文本，放到 matcher.group(0)
            System.out.println("找到：" + matcher.group(0));
        }
    }
}
